home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_081 / icon / icon.doc < prev    next >
Text File  |  1992-05-06  |  24KB  |  934 lines

  1. r
  2. H
  3.  
  4.  
  5.  
  6.  
  7.  
  8.               An Overview of Version 5 of the Icon
  9.                       Programming Language
  10.  
  11.  
  12.  
  13.  
  14. 1.  Introduction
  15.  
  16.    Icon is a high-level programming language with extensive
  17. facilities for processing strings and lists. Icon has several
  18. novel features, including expressions that may produce sequences
  19. of results, goal-directed evaluation that automatically searches
  20. for a successful result, and string scanning that allows opera-
  21. tions on strings to be formulated at a high conceptual level.
  22.  
  23.    Icon resembles SNOBOL4 [1] in its emphasis on high-level
  24. string processing and a design philosophy that allows ease of
  25. programming and short, concise programs. Like SNOBOL4, storage
  26. allocation and garbage collection are automatic in Icon, and
  27. there are few restrictions on the sizes of objects. Strings,
  28. lists, and other structures are created during program execution
  29. and their size does not need to be known when a program is writ-
  30. ten.  Values are converted to expected types automatically; for
  31. example, numeral strings read in as input can be used in numeri-
  32. cal computations without explicit conversion.  Whereas SNOBOL4
  33. has a pattern-matching facility that is separate from the rest of
  34. the language, string scanning is integrated with the rest of the
  35. language facilities in Icon.  Unlike SNOBOL4, Icon has an
  36. expression-based syntax with reserved words; in appearance, Icon
  37. programs resemble those of several other conventional programming
  38. languages.
  39.  
  40.    Examples of the kinds of problems for which Icon is well
  41. suited are:
  42.  
  43.      +  text analysis, editing, and formatting
  44.  
  45.      +  document preparation
  46.  
  47.      +  symbolic mathematics
  48.  
  49.      +  text generation
  50.  
  51.      +  parsing and translation
  52.  
  53.      +  data laundry
  54.  
  55.      +  graph manipulation
  56.  
  57.    Version 5 of Icon is implemented in C [2]. There are UNIX*
  58. implementations for the AT&T 3B20, PDP-11, Ridge 32, Sun
  59.                           
  60. *UNIX is a trademark of AT&T Bell Laboratories.
  61.  
  62.  
  63.  
  64.  
  65.                               - 1 -
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74. Workstation, and VAX-11.  There also is a VMS implementation for
  75. the VAX-11 and an MS-DOS implementation for personal computers.
  76. Other implementations are in progress.
  77.  
  78.    An earlier version of Icon [3] is available on several large-
  79. scale computers, including the CRAY-1, DEC-10, IBM 360/370, PRIME
  80. 450/550/650, and CDC Cyber/6000.
  81.  
  82.    A brief description of some of the representative features of
  83. Icon is given in the following sections. This description is not
  84. rigorous and does not include many features of Icon. See [4] for
  85. a complete description of Version 5 and [5] for a description of
  86. recent additions to the language.
  87.  
  88.  
  89. 2.  Strings
  90.  
  91.    Strings of characters may be arbitrarily long, limited only by
  92. the architecture of the computer on which Icon is implemented. A
  93. string may be specified literally by enclosing it in double quo-
  94. tation marks, as in
  95.  
  96.         greeting := "Hello world"
  97.  
  98. which assigns an 11-character string to greeting, and
  99.  
  100.         address := ""
  101.  
  102. which assigns the zero-length empty string to address.  The
  103. number of characters in a string s, its size, is given by *s. For
  104. example, *greeting is 11 and *address is 0.
  105.  
  106.    Icon uses the ASCII character set, extended to 256 characters.
  107. There are escape conventions, similar to those of C, for
  108. representing characters that cannot be keyboarded.
  109.  
  110.    Strings also can be read in and written out, as in
  111.  
  112.         line := read()
  113.  
  114. and
  115.  
  116.         write(line)
  117.  
  118. Strings can be constructed by concatenation, as in
  119.  
  120.         element := "(" || read() || ")"
  121.  
  122. If the concatenation of a number of strings is to be written out,
  123. the write function can be used with several arguments to avoid
  124. actual concatenation:
  125.  
  126.         write("(",read(),")")
  127.  
  128.  
  129.  
  130.  
  131.                               - 2 -
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.    Substrings can be formed by subscripting strings with range
  141. specifications that indicate, by position, the desired range of
  142. characters. For example,
  143.  
  144.         middle := line[10:20]
  145.  
  146. assigns to middle the string of characters of line between posi-
  147. tions 10 and 20.  Similarly,
  148.  
  149.         write(line[2])
  150.  
  151. writes the second character of line.  The value 0 is used to
  152. refer to the position after the last character of a string. Thus
  153.  
  154.         write(line[2:0])
  155.  
  156. writes the substring of line from the second character to the
  157. end, thus omitting the first character.
  158.  
  159.    An assignment can be made to the substring of string-valued
  160. variable to change its value. For example,
  161.  
  162.         line[2] := "..."
  163.  
  164. replaces the second character of line by three dots. Note that
  165. the size of line changes automatically.
  166.  
  167.    There are many functions for analyzing strings. An example is
  168.  
  169.         find(s1,s2)
  170.  
  171. which produces the position in s2 at which s1 occurs as a sub-
  172. string. For example, if the value of greeting is as given ear-
  173. lier,
  174.  
  175.         find("or",greeting)
  176.  
  177. produces the value 8.  See Section 4.2 for the handling of situa-
  178. tions in which s1 does not occur in s2, or in which it occurs at
  179. several different positions.
  180.  
  181.  
  182. 3.  Character Sets
  183.  
  184.    While strings are sequences of characters, csets are sets of
  185. characters in which membership rather than order is significant.
  186. Csets are represented literally using single enclosing quotation
  187. marks, as in
  188.  
  189.         vowels := 'aeiouAEIOU'
  190.  
  191. Two useful built-in csets are &lcase and &ucase, which consist of
  192. the lowercase and uppercase letters, respectively.  Set opera-
  193. tions are provided for csets. For example,
  194.  
  195.  
  196.  
  197.                               - 3 -
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.         letters := &lcase ++ &ucase
  207.  
  208. forms the cset union of the lowercase and uppercase letters and
  209. assigns the resulting cset to letters, while
  210.  
  211.         consonants := letters -- 'aeiouAEIOU'
  212.  
  213. forms the cset difference of the letters and the vowels and
  214. assigns the resulting cset to consonants.
  215.  
  216.    Csets are useful in situations in which any one of a number of
  217. characters is significant. An example is the string analysis
  218. function
  219.  
  220.         upto(c,s)
  221.  
  222. which produces the position s at which any character in c occurs.
  223. For example,
  224.  
  225.         upto(vowels,greeting)
  226.  
  227. produces 2. Another string analysis function that uses csets is
  228.  
  229.         many(c,s)
  230.  
  231. which produces the position in s after an initial substring con-
  232. sisting only of characters that occur in s.  An example of the
  233. use of many is in locating words. Suppose, for example, that a
  234. word is defined to consist of a string of letters.  The expres-
  235. sion
  236.  
  237.         write(line[1:many(letters,line)])
  238.  
  239. writes a word at the beginning of line. Note the use of the posi-
  240. tion returned by a string analysis function to specify the end of
  241. a substring.
  242.  
  243.  
  244. 4.  Expression Evaluation
  245.  
  246. 4.1  Conditional Expressions
  247.  
  248.    In Icon there are conditional expressions that may succeed and
  249. produce a result, or may fail and not produce any result. An
  250. example is the comparison operation
  251.  
  252.         i > j
  253.  
  254. which succeeds (and produces the value of j) provided that the
  255. value of i is greater than the value of j, but fails otherwise.
  256.  
  257.    The success or failure of conditional operations is used
  258. instead of Boolean values to drive control structures in Icon. An
  259. example is
  260.  
  261.  
  262.  
  263.                               - 4 -
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.         if i > j then k := i else k := j
  273.  
  274. which assigns the value of i to k if the value of i is greater
  275. than the value of j, but assigns the value of j to k otherwise.
  276.  
  277.    The usefulness of the concepts of success and failure is
  278. illustrated by find(s1,s2), which fails if s1 does not occur as a
  279. substring of s2.  Thus
  280.  
  281.         if i := find("or",line) then write(i)
  282.  
  283. writes the position at which or occurs in line, if it occurs, but
  284. does not write a value if it does not occur.
  285.  
  286.    Many expressions in Icon are conditional. An example is
  287. read(), which produces the next line from the input file, but
  288. fails when the end of the file is reached. The following expres-
  289. sion is typical of programming in Icon and illustrates the
  290. integration of conditional expressions and conventional control
  291. structures:
  292.  
  293.         while line := read() do
  294.            write(line)
  295.  
  296. This expression copies the input file to the output file.
  297.  
  298.    If an argument of a function fails, the function is not
  299. called, and the function call fails as well. This "inheritance"
  300. of failure allows the concise formulation of many programming
  301. tasks. Omitting the optional do clause in while-do, the previous
  302. expression can be rewritten as
  303.  
  304.         while write(read())
  305.  
  306.  
  307. 4.2  Generators
  308.  
  309.    In some situations, an expression may be capable of producing
  310. more than one result. Consider
  311.  
  312.         sentence := "Store it in the neighboring harbor"
  313.         find("or",sentence)
  314.  
  315. Here or occurs in sentence at positions 3, 23, and 33. Most pro-
  316. gramming languages treat this situation by selecting one of the
  317. positions, such as the first, as the result of the expression. In
  318. Icon, such an expression is a generator and is capable of produc-
  319. ing all three positions.
  320.  
  321.    The results that a generator produces depend on context. In a
  322. situation where only one result is needed, the first is produced,
  323. as in
  324.  
  325.  
  326.  
  327.  
  328.  
  329.                               - 5 -
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.         i := find("or",sentence)
  339.  
  340. which assigns the value 3 to i.
  341.  
  342.    If the result produced by a generator does not lead to the
  343. success of an enclosing expression, however, the generator is
  344. resumed to produce another value. An example is
  345.  
  346.         if (i := find("or",sentence)) > 5 then write(i)
  347.  
  348. Here the first result produced by the generator, 3, is assigned
  349. to i, but this value is not greater than 5 and the comparison
  350. operation fails. At this point, the generator is resumed and pro-
  351. duces the second position, 23, which is greater than 5. The com-
  352. parison operation then succeeds and the value 23 is written.
  353. Because of the inheritance of failure and the fact that com-
  354. parison operations return the value of their right argument, this
  355. expression can be written in the following more compact form:
  356.  
  357.         write(5 < find("or",sentence))
  358.  
  359.  
  360.    Goal-directed evaluation is inherent in the expression evalua-
  361. tion mechanism of Icon and can be used in arbitrarily complicated
  362. situations.  For example,
  363.  
  364.         find("or",sentence1) = find("and",sentence2)
  365.  
  366. succeeds if or occurs in sentence1 at the same position as and
  367. occurs in sentence2.
  368.  
  369.    A generator can be resumed repeatedly to produce all its
  370. results by using the every-do control structure. An example is
  371.  
  372.         every i := find("or",sentence)
  373.            do write(i)
  374.  
  375. which writes all the positions at which or occurs in sentence.
  376. For the example above, these are 3, 23, and 33.
  377.  
  378.    Generation is inherited like failure, and this expression can
  379. be written more concisely by omitting the optional do clause:
  380.  
  381.         every write(find("or",sentence))
  382.  
  383.  
  384.    There are several built-in generators in Icon. One of the most
  385. frequently used of these is
  386.  
  387.         i to j
  388.  
  389. which generates the integers from i to j. This generator can be
  390. combined with every-do to formulate the traditional for-style
  391. control structure:
  392.  
  393.  
  394.  
  395.                               - 6 -
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.         every k := i to j do
  405.            f(k)
  406.  
  407. Note that this expression can be written more compactly as
  408.  
  409.         every f(i to j)
  410.  
  411.  
  412.    There are a number of other control structures related to gen-
  413. eration.  One is alternation,
  414.  
  415.         expr1 | expr2
  416.  
  417. which generates the results of expr1 followed by the results of
  418. expr2.  Thus
  419.  
  420.         every write(find("or",sentence1) | find("or",sentence2))
  421.  
  422. writes the positions of or in sentence1 followed by the positions
  423. of or in sentence2. Again, this sentence can be written more com-
  424. pactly by using alternation in the second argument of find:
  425.  
  426.         every write(find("or",sentence1 | sentence2))
  427.  
  428.  
  429.    Another use of alternation is illustrated by
  430.  
  431.         (i | j | k) = (0 | 1)
  432.  
  433. which succeeds if any of i, j, or k has the value 0 or 1.
  434.  
  435.  
  436. 5.  String Scanning
  437.  
  438.    The string analysis and synthesis operations described in Sec-
  439. tions 2 and 3 work best for relatively simple operations on
  440. strings.  For complicated operations, the bookkeeping involved in
  441. keeping track of positions in strings becomes burdensome and
  442. error prone.  In such cases, Icon has a string scanning facility
  443. that is analogous in many respects to pattern matching in SNO-
  444. BOL4. In string scanning, positions are managed automatically and
  445. attention is focused on a current position in a string as it is
  446. examined by a sequence of operations.
  447.  
  448.    The string scanning operation has the form
  449.  
  450.         s ? expr
  451.  
  452. where s is the subject string to be examined and expr is an
  453. expression that performs the examination.  A position in the sub-
  454. ject, which starts at 1, is the focus of examination.
  455.  
  456.    Matching functions change this position.  One matching func-
  457. tion, move(i), moves the position by i and produces the substring
  458.  
  459.  
  460.  
  461.                               - 7 -
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470. of the subject between the previous and new positions. If the
  471. position cannot be moved by the specified amount (because the
  472. subject is not long enough), move(i) fails. A simple example is
  473.  
  474.         line ? while write(move(2))
  475.  
  476. which writes successive two-character substrings of line, stop-
  477. ping when there are no more characters.
  478.  
  479.    Another matching function is tab(i), which sets the position
  480. in the subject to i and also returns the substring of the subject
  481. between the previous and new positions.  For example,
  482.  
  483.         line ? if tab(10) then write(tab(0))
  484.  
  485. first sets the position in the subject to 10 and then to the end
  486. of the subject, writing line[10:0].  Note that no value is writ-
  487. ten if the subject is not long enough.
  488.  
  489.    String analysis functions such as find can be used in string
  490. scanning. In this context, the string that they operate on is not
  491. specified and is taken to be the subject. For example,
  492.  
  493.         line ? while write(tab(find("or")))
  494.            do move(2)
  495.  
  496. writes all the substrings of line prior to occurrences of or.
  497. Note that find produces a position, which is then used by tab to
  498. change the position and produce the desired substring. The
  499. move(2) skips the or that is found.
  500.  
  501.    Another example of the use of string analysis functions in
  502. scanning is
  503.  
  504.         line ? while tab(upto(letters)) do
  505.            write(tab(many(letters)))
  506.  
  507. which writes all the words in line.
  508.  
  509.    As illustrated in the examples above, any expression may occur
  510. in the scanning expression. Unlike SNOBOL4, in which the opera-
  511. tions that are allowed in pattern matching are limited and
  512. idiosyncratic, string scanning is completely integrated with the
  513. rest of the operation repertoire of Icon.
  514.  
  515.  
  516. 6.  Structures
  517.  
  518. 6.1  Lists
  519.  
  520.    While strings are sequences of characters, lists in Icon are
  521. sequences of values of arbitrary types. Lists are created by
  522. enclosing the lists of values in brackets. An example is
  523.  
  524.  
  525.  
  526.  
  527.                               - 8 -
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.         car1 := ["buick","skylark",1978,2450]
  537.  
  538. in which the list car1 has four values, two of which are strings
  539. and two of which are integers. Note that the values in a list
  540. need not all be of the same type. In fact, any kind of value can
  541. occur in a list -- even another list, as in
  542.  
  543.         inventory := [car1,car2,car3,car4]
  544.  
  545.  
  546.    Lists also can be created by
  547.  
  548.         a := list(i,x)
  549.  
  550. which creates a list of i values, each of which has the value x.
  551.  
  552.    The values in a list can be referenced by position much like
  553. the characters in a string. Thus
  554.  
  555.         car1[4] := 2400
  556.  
  557. changes the last value in car1 to 2400.  A reference that is out
  558. of the range of the list fails. For example,
  559.  
  560.         write(car1[5])
  561.  
  562. fails.
  563.  
  564.    The values in a list a are generated by !a. Thus
  565.  
  566.         every write(!a)
  567.  
  568. writes all the values in a.
  569.  
  570.    Lists can be manipulated like stacks and queues. The function
  571. push(a,x) adds the value of x to the left end of the list a,
  572. automatically increasing the size of a by one. Similarly, pop(a)
  573. removes the leftmost value from a, automatically decreasing the
  574. size of a by one, and produces the removed value.
  575.  
  576.    A list value in Icon is a pointer (reference) to a structure.
  577. Assignment of a structure in Icon does not copy the structure
  578. itself but only the pointer to it. Thus the result of
  579.  
  580.         demo := car1
  581.  
  582. causes demo and car1 to reference the same list. Graphs with
  583. loops can be constructed in this way. For example,
  584.  
  585.         node1 := ["a"]
  586.         node2 := [node1,"b"]
  587.         push(node1,node2)
  588.  
  589.  
  590.  
  591.  
  592.  
  593.                               - 9 -
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602. constructs a structure that can be pictured as follows:
  603.  
  604.  
  605.           node1  .->a--.
  606.                  |     |
  607.                  |     |
  608.           node2  '--b<-'
  609.  
  610.  
  611.  
  612. 6.2  Tables
  613.  
  614.    Icon has a table data type similar to that of SNOBOL4. Tables
  615. essentially are sets of pairs of values, an entry value and a
  616. corresponding assigned value. The entry and assigned values may
  617. be of any type, and the assigned value for any entry value can be
  618. looked up automatically.  Thus tables provide a form of associa-
  619. tive access in contrast with the positional access to values in
  620. lists.
  621.  
  622.    A table is created by an expression such as
  623.  
  624.         symbols := table(x)
  625.  
  626. which assigns to symbols a table with the default assigned value
  627. x.  Subsequently, symbols can be referenced by any entry value,
  628. such as
  629.  
  630.         symbols["there"] := 1
  631.  
  632. which assigns the value 1 to the thereth entry in symbols.
  633.  
  634.    Tables grow automatically as new entry values are added.  For
  635. example, the following program segment produces a table contain-
  636. ing a count of the words that appear in the input file:
  637.  
  638.         words := table(0)
  639.         while line := read() do
  640.            line ? while tab(upto(letters)) do
  641.               words[tab(many(letters))] +:= 1
  642.  
  643. Here the default assigned value for each word is 0, as given in
  644. table(0), and +:= is an augmented assignment operation that
  645. increments the assigned values by one.  There are augmented
  646. assignment operations for all binary operators.
  647.  
  648.    Tables can be converted to lists, so that their entry and
  649. assigned values can be accessed by position.  This is done by
  650. sort(t), which produces a list of two-element lists from t, where
  651. each two-element list consists of an entry value and its
  652. corresponding assigned value. For example,
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.                              - 10 -
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.         wordlist := sort(words)
  669.         every pair := !wordlist do
  670.            write(pair[1]," : ",pair[2])
  671.  
  672. writes the words and their counts from words.
  673.  
  674.  
  675. 7.  Procedures
  676.  
  677.    An Icon program consists of a sequence of procedure declara-
  678. tions.  An example of a procedure declaration is
  679.  
  680.         procedure max(i,j)
  681.            if i > j then return i else return j
  682.         end
  683.  
  684. where the name of the procedure is max and its formal parameters
  685. are i and j. The return expressions return the value of i or j,
  686. whichever is larger.
  687.  
  688.    Procedures are called like built-in functions. Thus
  689.  
  690.         k := max(*s1,*s2)
  691.  
  692. assigns to k the size of the longer of the strings s1 and s2.
  693.  
  694.    A procedure also may suspend instead of returning. In this
  695. case, a result is produced as in the case of a return, but the
  696. procedure can be resumed to produce other results. An example is
  697. the following procedure that generates the words in the input
  698. file.
  699.  
  700.         procedure genword()
  701.            local line, letters, words
  702.            letters := &lcase ++ &ucase
  703.            while line := read() do
  704.               line ? while tab(upto(letters)) do {
  705.                  word := tab(many(letters))
  706.                  suspend word
  707.                  }
  708.         end
  709.  
  710. The braces enclose a compound expression.
  711.  
  712.    Such a generator is used in the same way that a built-in gen-
  713. erator is used. For example
  714.  
  715.         every word := genword() do
  716.            if find("or",word) then write(word)
  717.  
  718. writes only those words that contain the substring or.
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.                              - 11 -
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.  
  734. 8.  An Example
  735.  
  736.    The following program sorts graphs topologically.
  737.  
  738.         procedure main()
  739.            local sorted, nodes, arcs, roots
  740.            while nodes := read() do {      # get next node list
  741.               arcs := read()               # get arc list
  742.               sorted := ""                 # sorted nodes
  743.                                            # get nodes without predecessors
  744.               while *(roots := nodes -- snodes(arcs)) > 0 do {
  745.                  sorted ||:= roots         # add to sorted nodes
  746.                  nodes --:= roots          # delete these nodes
  747.                  arcs := delarcs(arcs,roots)# delete their arcs
  748.                  }
  749.               if *arcs = 0 then write(sorted)# successfully sorted
  750.               else write("graph has cycle")# cycle if node remains
  751.            }
  752.         end
  753.  
  754.  
  755.         procedure snodes(arcs)
  756.            local nodes
  757.            nodes := ""
  758.            arcs ? while move(1) do {       # predecessor
  759.               move(2)                      # skip "->"
  760.               nodes ||:= move(1)           # successor
  761.               move(1)                      # skip ";"
  762.               }
  763.            return nodes
  764.         end
  765.  
  766.  
  767.         procedure delarcs(arcs,roots)
  768.            local newarcs, node
  769.            newarcs := ""
  770.            arcs ? while node := move(1) do {# get predecessor node
  771.               if many(roots,node) then move(4)# delete arc from root node
  772.               else newarcs ||:= node || move(4)# else keep arc
  773.               }
  774.            return newarcs
  775.         end
  776.  
  777. Graph nodes are represented by single characters with a list of
  778. the nodes on one input line followed by a list of arcs. For exam-
  779. ple, the graph
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.                              - 12 -
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.                   .---------------.
  801.                   |               |
  802.                   |               |
  803.                   a------>b------>c
  804.                   |       |       |
  805.                   |       |       |
  806.                   |       v       |
  807.                   d------>e-------'
  808.  
  809.  
  810. is given as
  811.  
  812.         abcde
  813.         a->b;a->c;b->c;b->e;d->a;d->e;e->c;
  814.  
  815. for which the output is
  816.  
  817.         dabec
  818.  
  819.  
  820.    The nodes are represented by csets and automatic type conver-
  821. sion is used to convert strings to csets and vice versa.  Note
  822. the use of augmented assignment operations for concatenation and
  823. in the computation of cset differences.
  824.  
  825. Acknowledgement
  826.  
  827.    Icon was designed by the the author in collaboration with Dave
  828. Hanson, Tim Korb, Cary Coutant, and Steve Wampler. The current
  829. implementation is largely the work of Cary Coutant and Steve
  830. Wampler with recent contributions by Bill Mitchell.  Dave Hanson
  831. and Bill Mitchell also made several helpful suggestions on the
  832. presentation of material in this paper.
  833.  
  834. References
  835.  
  836.  
  837. 1. Griswold, Ralph E., Poage, James F., and Polonsky, Ivan P.
  838.    The SNOBOL4 Programming Language, second edition.  Prentice-
  839.    Hall, Inc., Englewood Cliffs, New Jersey. 1971.
  840.  
  841. 2. Kernighan, Brian W. and Ritchie, Dennis M. The C Programming
  842.    Language. Prentice-Hall, Inc., Englewood Cliffs, New Jersey.
  843.    1978.
  844.  
  845. 3. Griswold, Ralph E. Differences Between Versions 2 and 5 of
  846.    Icon, Technical Report TR 83-5, Department of Computer Sci-
  847.    ence, The University of Arizona. 1983.
  848.  
  849. 4. Griswold, Ralph E. and Griswold, Madge T. The Icon Programming
  850.    Language. Prentice-Hall, Inc., Englewood Cliffs, New Jersey.
  851.    1983.
  852.  
  853.  
  854.  
  855.  
  856.  
  857.                              - 13 -
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866. 5. Griswold, Ralph E. Extensions to Version 5 of the Icon Pro-
  867.    gramming Language, Technical report, Department of Computer
  868.    Science, The University of Arizona. 1985.
  869.  
  870.  
  871.  
  872.  
  873.    Ralph E. Griswold
  874.    Department of Computer Science
  875.    The University of Arizona
  876.  
  877.    September 30, 1985
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.                              - 14 -
  924.  
  925.  
  926.  
  927.  
  928. HPress <CR> to continue !
  929. H
  930. [76703,750]
  931. ICON.DOC                  06-Jul-86 24265              67
  932.  
  933. Enter command, N for next file
  934. or <CR> for disposition menu !